package org.yan.kangaroo.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.yan.kangaroo.common.response.BaseResponseCodeEnum;
import org.yan.kangaroo.common.response.Result;
import org.yan.kangaroo.common.util.JsonUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 认证过滤器
 *
 * @author wangx 2020/05/21 8:29
 */
@Component
@Slf4j
public class AuthFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        String token = Objects.requireNonNull(request.getHeaders().getFirst("Authorization"));
        if (StringUtils.isBlank(token)) {
            Result<?> result = Result.error(BaseResponseCodeEnum.NOT_LOGGED_IN);
            String json = JsonUtils.getInstance().toJson(result);
            DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(json.getBytes(StandardCharsets.UTF_8));
            exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
            exchange.getResponse().setStatusCode(HttpStatus.OK);
            return exchange.getResponse().writeWith(Flux.just(buffer));
        }
        String requestUri = request.getURI().toString();
        String queryString = request.getQueryParams().toString();
        HttpMethod requestMethod = request.getMethod();
        if (!HttpMethod.GET.equals(requestMethod)) {
            Flux<DataBuffer> body = request.getBody();
            log.info("body:{}", body);

        }
        String ip = Objects.requireNonNull(request.getRemoteAddress()).getAddress().getHostAddress();
        assert requestMethod != null;
        log.info("[filter] 认证过滤器 ip:{}, method:{},requestURI:{},queryString:{}", ip, requestMethod.name(), requestUri, queryString);
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
